home *** CD-ROM | disk | FTP | other *** search
- /*
- File: GetEnetAddrDirect.c
-
- Contains: This is a sample program to obtain the ethernet address from a Power Mac using
- 1. direct access to the ROM for the 61/71/8100 Power Macs, or by accessing the
- Name Registry for PCI based systems. This means that the the address can be
- accessed without Open Transport being available, or without having to open the
- Ethernet device driver.
-
- 2. use OpenTransport to display the ethernet address for all ethernet devices
- that are detected. For this method to work, the program opens a connection over
- the found ethernet port. If the openConnection call works, then we can use the
- OT APIs to obtain the ethernet address.
-
- For the earlier Power Macs, 6100/ 7100/8100, the Burned In Address is found in
- ROM at address 0x50f08000. One must read every 16 bytes for each of the 6
- bytes that make up the address. That is you'll need to
- read address 50f08000, 50f08010, 50f08020, 50f08030, 50f08040,
- and 50f08050. The found address is byte swapped. which means
-
- 10 00 E0 2B 06 AF, which if you bit invert each byte becomes
-
- 08 00 07 D4 60 F5.
-
- For PCI Power Macs, the burned in address is generally in
- the Name Registry, however, the name of the entry is vendor
- specified. For the 72/73/75/76/85/86/95/9600 Power Macs, look at the
- "local-mac-address" entry. For the PCI Power Macs which use the Comm Slot2
- card, look at the "ASNT,ethernet-address" entry for a pointer to where the
- ethernet address is stored.
-
- The one set of Power Macs, that this program does not demonstrate how to access
- using the direct means are the 52/53/62/6300 systems which use the original
- CommSlot Ethernet card and which can also use the PDS slot LC style ethernet
- card
-
- Written by: Rich Kubota
-
- Copyright: Copyright © 1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 7/22/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
-
-
- */
- #include <MacTypes.h>
- #include <Gestalt.h>
- #include <Errors.h>
- #include <NameRegistry.h>
- #include <stdio.h>
- #include <Strings.h>
- #include <OpenTransport.h>
- #include <OpenTptLinks.h>
- #include <OpenTptConfig.h>
-
-
- enum {
- kUnsupported = 0,
- kPDMMachine = 1,
- kPCIMachine = 2,
- kCommSlotMachine = 3,
- kPCIComm2Machine = 4
- };
-
- enum {
- kPDMEnetROMBase = 0x50f08000
- };
-
- enum {
- gestaltPowerBookG3SeriesFSTN = 314,
- gestaltiMac = 406
- };
-
- struct Address8022
- {
- OTAddressType fAddrFamily;
- UInt8 fHWAddr[k48BitAddrLength];
- UInt16 fSAP;
- UInt8 fSNAP[k8022SNAPLength];
- };
- typedef struct Address8022 Address8022;
-
- UInt32 DoesCPUHaveBuiltInEthernet(void);
- UInt8 ByteSwapValue(UInt8 val);
- OSStatus GetPDMBuiltInEnetAddr(UInt8 *enetaddr);
- OSStatus GetPCIBuiltInEnetAddr(UInt8 *enetaddr);
- OSStatus GetPCIComm2EnetAddr(UInt8 *enetaddr);
- void DisplayEnetAddr(UInt8 *enetaddr);
- void DisplayBurnedInAddress(void);
- void DisplayOTEthernetAddresses(void);
-
-
- UInt32 DoesCPUHaveBuiltInEthernet(void)
- {
- long response;
- OSStatus err;
- UInt32 result = kUnsupported;
-
- err = Gestalt(gestaltMachineType, &response);
- switch (response)
- {
- case gestaltPowerMac8100_120:
- case gestaltAWS9150_80:
- case gestaltPowerMac8100_110:
- case gestaltPowerMac7100_80:
- case gestaltPowerMac8100_100:
- case gestaltAWS9150_120:
- case gestaltPowerMac8100_80:
- case gestaltPowerMac6100_60:
- case gestaltPowerMac6100_66:
- case gestaltPowerMac7100_66:
- result = kPDMMachine;
- break;
-
- case gestaltPowerMac9500:
- case gestaltPowerMac7500:
- case gestaltPowerMac8500:
- case gestaltPowerBook3400:
- case gestaltPowerBookG3:
- case gestaltPowerMac7200:
- case gestaltPowerMac7300:
- case gestaltPowerBookG3Series:
- case gestaltPowerBookG3SeriesFSTN:
- case gestaltPowerMacG3:
- case gestaltiMac:
- result = kPCIMachine;
- break;
-
- case gestaltPowerMac5200:
- case gestaltPowerMac6200:
- result = kCommSlotMachine;
- break;
-
- case gestaltPowerMac6400:
- case gestaltPowerMac5400:
- case gestaltPowerMac5500:
- case gestaltPowerMac6500:
- case gestaltPowerMac4400_160:
- case gestaltPowerMac4400:
- result = kPCIComm2Machine;
-
- }
-
- if (response == kUnsupported)
- {
- err = Gestalt(gestaltNameRegistryVersion, (long*) &response);
- if (err == noErr)
- result = kPCIMachine;
- }
- return result;
- }
-
- UInt8 ByteSwapValue(UInt8 val)
- {
- UInt8 result = 0;
-
- if (val & 0x01)
- result |= 0x80;
-
- if (val & 0x02)
- result |= 0x40;
-
- if (val & 0x04)
- result |= 0x20;
-
- if (val & 0x08)
- result |= 0x10;
-
- if (val & 0x10)
- result |= 0x08;
-
- if (val & 0x20)
- result |= 0x04;
-
- if (val & 0x40)
- result |= 0x02;
-
- if (val & 0x80)
- result |= 0x01;
- return result;
- }
-
- OSStatus GetPDMBuiltInEnetAddr(UInt8 *enetaddr)
- {
- UInt32 i;
- UInt8 *val;
-
- for (i = 0; i < 6; i++)
- {
- val = (UInt8 *)(kPDMEnetROMBase + i * 0x10);
- enetaddr[i] = ByteSwapValue(*val);
- }
- return noErr;
- }
-
-
- OSStatus GetPCIBuiltInEnetAddr(UInt8 *enetaddr)
- {
- OSStatus err = noErr;
- RegEntryIter cookie;
- RegEntryID theFoundEntry;
- unsigned char enetAddrStr[32] = "\plocal-mac-address";
- RegCStrEntryNamePtr enetAddrCStr = p2cstr( enetAddrStr );
- RegEntryIterationOp iterOp;
- UInt8 enetAddr[6];
- Boolean done = false;
- RegPropertyValueSize theSize;
-
- err = RegistryEntryIDInit( &theFoundEntry );
- if (err != noErr)
- {
- fprintf(stdout, "RegistryEntryIDInit failed\n");
- return err;
- }
-
- err = RegistryEntryIterateCreate( &cookie );
- if (err != noErr)
- {
- fprintf(stdout, "RegistryEntryIterateCreate failed\n");
- return err;
- }
-
- iterOp = kRegIterDescendants;
-
- err = RegistryEntrySearch( &cookie, iterOp, &theFoundEntry, &done,
- enetAddrCStr, nil, 0);
-
- if (err == noErr)
- {
- theSize = sizeof(enetAddr);;
- err = RegistryPropertyGet(&theFoundEntry, enetAddrCStr, &enetAddr, &theSize );
- if (err == noErr)
- BlockMove(enetAddr, enetaddr, sizeof(enetAddr));
- }
-
- RegistryEntryIterateDispose( &cookie );
-
- return noErr;
- }
-
- OSStatus GetPCIComm2EnetAddr(UInt8 *enetaddr)
- {
- OSStatus err = noErr;
- RegEntryIter cookie;
- RegEntryID theFoundEntry;
- unsigned char enetAddrStr[32] = "\pASNT,ethernet-address";
- RegCStrEntryNamePtr enetAddrCStr = p2cstr( enetAddrStr );
- RegEntryIterationOp iterOp;
- UInt8 *enetAddr;
- Boolean done = false;
- RegPropertyValueSize theSize;
-
- err = RegistryEntryIDInit( &theFoundEntry );
- if (err != noErr)
- {
- fprintf(stdout, "RegistryEntryIDInit failed\n");
- return err;
- }
-
- err = RegistryEntryIterateCreate( &cookie );
- if (err != noErr)
- {
- fprintf(stdout, "RegistryEntryIterateCreate failed\n");
- return err;
- }
-
- iterOp = kRegIterDescendants;
-
- err = RegistryEntrySearch( &cookie, iterOp, &theFoundEntry, &done,
- enetAddrCStr, nil, 0);
-
- if (err == noErr)
- {
- theSize = sizeof(enetAddr);;
- err = RegistryPropertyGet(&theFoundEntry, enetAddrCStr, &enetAddr, &theSize );
- if (err == noErr)
- BlockMove(enetAddr, enetaddr, 6);
- }
-
- RegistryEntryIterateDispose( &cookie );
-
- return noErr;
- }
-
- void DisplayEnetAddr(UInt8 *enetaddr)
- {
- fprintf(stdout, "%02X.",(int )enetaddr[0]);
- fprintf(stdout, "%02X.",(int )enetaddr[1]);
- fprintf(stdout, "%02X.",(int )enetaddr[2]);
- fprintf(stdout, "%02X.",(int )enetaddr[3]);
- fprintf(stdout, "%02X.",(int )enetaddr[4]);
- fprintf(stdout, "%02X",(int )enetaddr[5]);
- }
-
- void DisplayBurnedInAddress(void)
- {
- OSStatus err;
- UInt32 cputype;
- UInt8 enetaddr[6];
-
- fprintf(stdout, "First, get the burned-in ethernet address directly from ROM or NameRegistry\n");
- cputype = DoesCPUHaveBuiltInEthernet();
- switch (cputype)
- {
- case kPDMMachine:
- err = GetPDMBuiltInEnetAddr((UInt8*)enetaddr);
- if (err == noErr)
- {
- fprintf(stdout, "\nBurned-In address for Ethernet Built-In => ");
- DisplayEnetAddr((UInt8*)&enetaddr);
- }
- break;
-
- case kPCIMachine:
- err = GetPCIBuiltInEnetAddr((UInt8*)enetaddr);
- if (err == noErr)
- {
- fprintf(stdout, "\nBurned-In address for Ethernet Built-In => ");
- DisplayEnetAddr((UInt8*)&enetaddr);
- }
- break;
-
- case kCommSlotMachine:
- fprintf(stdout, "\n\nThis is a NuBus based Power Mac which may have a CommSlot Ethernet card");
- fprintf(stdout, "\nmust use Open Transport to obtain the ethernet address");
- break;
-
- case kPCIComm2Machine:
- fprintf(stdout, "\n\nThis is a PCI system which may have a CommSlot2 Ethernet card");
- fprintf(stdout, "\nmust use Open Transport to obtain the ethernet address");
- break;
-
- default:
- fprintf(stdout, "\n It appears that this CPU does not have built-in ethernet\n");
- break;
- }
- }
-
- void DisplayOTEthernetAddresses(void)
- {
- OSStatus status;
- EndpointRef ep;
- OTPortRecord devicePortRecord;
- UInt32 index;
- TBind returnInfo;
- TBind requestInfo;
- Address8022 theReturnAddr = {AF_8022, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x0000,
- {0x00,0x00,0x00,0x00,0x00}};
- Address8022 theAddr = {AF_8022, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0x8888,
- {0x00,0x00,0x00,0x00,0x00}};
- Boolean foundAPort;
- Str255 userFriendlyName;
-
-
- if (status = InitOpenTransport())
- {
- fprintf(stdout, "\n\nOpen Transport is not installed or is inactive\n");
- return;
- }
- else
- {
- fprintf(stdout, "\n\nNow checking for Ethernet addresses using Open Transport\n");
- fprintf(stdout, "There will be a slight delay as I try to open a connection\n");
- fprintf(stdout, "over each card.\n");
- }
-
- index = 0;
- // iterate thru each OT port record for ethernet ports.
- while (foundAPort = OTGetIndexedPort(&devicePortRecord,index))
- {
- if ((devicePortRecord.fCapabilities & kOTPortIsDLPI) &&
- (devicePortRecord.fCapabilities & kOTPortIsTPI) &&
- (kOTEthernetDevice == OTGetDeviceTypeFromPortRef(devicePortRecord.fRef)))
- {
-
- ep = OTOpenEndpoint(OTCreateConfiguration(devicePortRecord.fPortName), (OTOpenFlags)NULL, NULL,&status);
-
- if (status == kOTNoError)
- {
- // we have to bind the endpoint before we can get it's address info
- requestInfo.addr.buf = (UInt8 *)&theAddr;
- requestInfo.addr.len = 10; // family type + Ethernet + type field
- // don't use sizeof(theAddr) since we are binding to type 1 Ethernet
- // address, not to an 802.2 address.
- requestInfo.addr.maxlen = 0;
- requestInfo.qlen = 0;
-
- status = OTBind(ep, &requestInfo, NULL);
-
- if (status == kOTNoError)
- {
- returnInfo.addr.buf = (UInt8 *)&theReturnAddr;
- returnInfo.addr.maxlen = 10; // family type + 6 bytes for Ethernet + type
- returnInfo.qlen = 0;
-
-
- status = OTGetProtAddress(ep,&returnInfo,NULL);
-
- if (status == kOTNoError)
- {
- OTGetUserPortNameFromPortRef(devicePortRecord.fRef, userFriendlyName);
- fprintf(stdout, "\n The Ethernet address for %#s is => ", userFriendlyName);
- DisplayEnetAddr((UInt8*)&theReturnAddr.fHWAddr);
- }
- OTUnbind(ep);
- }
-
- OTCloseProvider(ep);
- }
-
-
- }
- index++;
- }
-
-
-
- // closing down
- CloseOpenTransport();
-
-
- }
-
- main (void)
- {
-
- fprintf(stdout, "Sample program to obtain the available ethernet addresses");
- DisplayBurnedInAddress();
-
- DisplayOTEthernetAddresses();
- return 0;
- }
-